class LcInterface
{
public:

	LcInterface();
	void input( int argc, char * const argv[]);

	LcClassifier*  getClassifier(){ return my_classifier;}

	LcVideoReadExt getTrainVideo();
	LcVideoReadExt getTestVideo();


	bool IF_TRAIN;
	bool IF_TEST;

	int train_f_start;
	int train_f_end;
	int train_f_rate;

	int test_f_start;
	int test_f_end;
	int test_f_rate;

	int backup_start;
	int backup_end;
	int backup_rate;

	string root;

	string train_video_name;
	string test_video_name;

	string feature_code_string;

	string classifier_name;

	string addition_str;
	float classifier_affine_weight;

	void buildDatasetmap();

	map< string , Vec3i> data_map;

	bool setVideo( string name ,int & start, int & end , int & rate);
	void setClassifier();

	void init();

	int global_extractor_code;
	
	void setGlobalExtractor();

	LcClassifier* my_classifier;

	LcGlobalExtractor * my_global_extractor;
	

	bool IF_TRAIN_PER_FRAME;

	bool IF_KMEAN;

	bool IF_REG;

};

void LcInterface::setGlobalExtractor()
{
	switch( global_extractor_code/5)
	{
		case 0:
			my_global_extractor = new LcSpatialHistogram( global_extractor_code%5);
			break;
		case 1:
			my_global_extractor = new LcSpatialHoG( global_extractor_code%5);
			break;
	}
}

LcVideoReadExt LcInterface::getTrainVideo()
{
	LcVideoReadExt ans;
	ans.video_name = train_video_name;
	ans.f_start = train_f_start;
	ans.f_end = train_f_end;
	ans.f_rate = train_f_rate;
	ans.t_win = 0;
	ans.root = root;
	return ans;
}

LcVideoReadExt LcInterface::getTestVideo()
{
	LcVideoReadExt ans;
	ans.video_name = test_video_name;
	ans.f_start = test_f_start;
	ans.f_end = test_f_end;
	ans.f_rate = test_f_rate;
	ans.t_win = 0;
	ans.root = root;
	return ans;
}

void LcInterface::setClassifier()
{
	if(classifier_name == "rdt")
	{
		my_classifier = new LcRandomTrees;
	}
}
void LcInterface::init()
{
	if(IF_TEST == false)
	{
		cout << " into " << endl;
		if(train_f_start<0){
			train_f_start = test_f_start;
			if( backup_start >= 0 ) test_f_start = backup_start;
		}
		if(train_f_end<0)
		{
			train_f_end = test_f_end;
			if( backup_end >= 0 ) test_f_end = backup_end;
		}
		if(train_f_rate<0)
		{
			train_f_rate = test_f_rate;
			if( backup_start >= 0 ) test_f_rate = backup_rate;
		}
	}

	if(feature_code_string == "") feature_code_string = "l";

	if(classifier_name == "" ) classifier_name = "rdt";
	setClassifier();

	setGlobalExtractor();

	if(train_video_name == "" ){train_video_name = "GOPR2382_cab";}
	setVideo( train_video_name, train_f_start, train_f_end, train_f_rate);

	if(test_video_name == "" ){test_video_name = "GOPR2384_cab";}
	setVideo( test_video_name, test_f_start, test_f_end, test_f_rate);
}

LcInterface::LcInterface()
{
	train_f_start = -1;
	train_f_rate = -1;
	train_f_end = -1;

	test_f_start = -1;
	test_f_rate = -1;
	test_f_end = -1;

	backup_start = -1;
	backup_rate = -1;
	backup_end = -1;

	root = "./../_FGS/";
	train_video_name = "";
	test_video_name = "";
	feature_code_string = "";
	classifier_name = "";

	IF_TEST = false;
	IF_TRAIN = false;

	addition_str = "";
	classifier_affine_weight = 1.0f;

	buildDatasetmap();

	IF_TRAIN_PER_FRAME = false;

	global_extractor_code = 0;

	IF_KMEAN = false;

	IF_REG = false;
}

void LcInterface::buildDatasetmap()
{
	data_map.clear();
	data_map.insert( pair< string, Vec3i>( "GOPR2382_cab", Vec3i(150,5300,50)) );
	data_map.insert( pair< string, Vec3i>( "GOPR2384_cab", Vec3i(150,11200,25)) );
}

bool LcInterface::setVideo( string name ,int & start, int & end , int & rate)
{
	map<string , Vec3i>::iterator iter = data_map.find( name );
	if( iter != data_map.end())
	{
		Vec3i temp = iter->second;
		if(start<0)start = temp[0];
		if(end<0)end = temp[1];
		if(rate<0)rate = temp[2];
		return true;
	}
	else
	{
		cout << "One of Video is not in default" << endl;
		return false;
	}
}

void LcInterface::input( int argc, char * const argv[])
{
	for(int ind = 1;ind < argc;ind++)
	{
		/*** Parse switches ***/
		if (argv[ind][0] == '-') {
			switch (argv[ind][1]) {
				case 'w':
					classifier_affine_weight = float( atof(argv[++ind]) );
					break;
				case 'z':
					addition_str = string(argv[++ind]);
					break;
				case 'f':
					root = string(argv[++ind]);
					break;
				case 't':
					train_video_name = string(argv[++ind]);
					break;
				case 'p':
					test_video_name = string(argv[++ind]);
					break;
				case 'v':
					feature_code_string =  string(argv[++ind]);
					break;
				case 'a':
					IF_TRAIN = true;
					break;
				case 'b':
					IF_TEST = true;
					break;
				case 's':
					//only for predict video setting , for trainning video it's always solid with frame
					// unless it's no testing model then the test frame setting will be use
					// as training parameter
					test_f_start =  atoi(argv[++ind]);
					break;
				case 'e':
					test_f_end = atoi(argv[++ind]);
					break;				
				case 'r':
					test_f_rate = atoi(argv[++ind]);
					break;
				case 'S':
					train_f_start = backup_start = atoi(argv[++ind]);
					break;
				case 'E':
					train_f_end = backup_end = atoi(argv[++ind]);
					break;
				case 'R':
					train_f_rate = backup_rate = atoi(argv[++ind]);
					break;
				case 'c':
					classifier_name = string(argv[++ind]);
					break;

				case 'd':
					IF_TRAIN_PER_FRAME = true;
					break;
				case 'g':
					global_extractor_code = atoi(argv[++ind]);
					break;
				case 'h':
					IF_KMEAN = true;
					break;
				case 'i':
					IF_REG = true;
					break;

				default : printf("Unknown switch '%c'\n", argv[ind][1]);
				break;
			}
		}
	}

	init();
}